Skip to main content

Tuple

Tuple is like a anonymous struct with convenient light-weight syntax. A common usage of tuple is to enable return multiple value from functions. Tuple's value/type elements can be access with indexes or names(if any).

Tuple Type

A tuple type is a comma-separated list of types, enclosed in parentheses.

The tuple type is consisted by the type, name and order of its elements, means these types are different:

//they are different because different element order
comptime assert((i32, i8, char) != (i8, i32, char));

//they are different because different element types
comptime assert((bool) != (char));

//they are different because different element names
comptime assert((name: string, id: i32) != (book: string, bid: i32));

You can create a empty tuple with () or void:

comptime assert(() == void);    //they are the same

Tuple Literal

The syntaxes of tuple literals is just like the array literals:

empty_tup := (-){};
tup1 := (i8, char, bool){1, 'a', true};
tup2 := (a: i8, b: char, c: bool){a = 1, b = 'a', c = true};

Similarly, the type of tuple element could be omitted:

empty_tup := .{};
tup1 := .{1, 'a', true};
tup2 := .{a = 1, b = 'a', c = true};

Accessing Elements

Generally, a tuple has two types of elements: values and types. And tuple's elements can be accessed using indexes or names. So we have four syntax for accessing elements in tuple:

Using IndexesUsing Names
Accessing Types::[n]::TypeName
Accessing Values.[n].name

All elements in tuple could be accessed by indexes, but only named elements could be accessed by names:

tup mutable: (i8, end: char, do: bool) = .{1, end = 'b', do = true};
assert(tup.[0] == 1 and tup.[1] == 'b' and tup.[2] == true);
assert(tup::[0] == i8 and tup::[1] == char and tup::[2] == bool);

//only the named elements could be accessed by names:
assert(tup.end == 'b' and tup.do == true);
assert(tup::end == char and tup::do == bool);

Traversing Tuples

You can use the compile-time ranged loops to traverse tuples:

tup := .{a = 1, b = 'a', c = true};
comptime for(elem in tup) {
println(elem);
}
//will output:
//1
//a
//true

Decomposing Tuples

The decomposing syntax of tuple is like the structured binding in C++:

tup := .{a = 1, b = 'a', c = true};
[i, c, b] := tup;
assert(i == 1 and c == 'a' and b == true);

You can also create sub-tuples by decomposing them:

tup := .{1, "awa", "hello", true};
[i, sub_tup...] := tup;
assert(^sub_tup.getType() == (string, string, bool));

Slicing Tuples